from operator import itemgetter
from datetime import datetime

from pypalo.objects import server, cell

def constants(base_name, cube_name, god=None):
	"This function returns constants dictionary from olap"
	#beginning of function suite
	
	#Создается манипулятор олап сервера
	srv=server("admin", "ivushka2011", None, None, None, "sa-pc247", 7921)
	#Создается словарь олап сервера
	srv_dict=srv.dictionary()
	#Определяется ид базы данных
	base_id=srv_dict["names"][base_name]
	
	#Создается манипулятор базы данных
	db=srv.Database(base_id)
	#Создается словарь базы данных
	db_dict=db.dictionary()
	#Определяется ид куба данных
	cube_id=db_dict["cubes"]["names"][cube_name]
	
	#Определяется ид измерения Годы:
	years_id=db_dict["dims"]["names"]["ОтчетГод"]
	#Создается манипулятор измерения Годы:
	years=db.Dimension(years_id)
	#Создается словарь измерения Годы:
	years_dict=years.dictionary()
	
	#Определяется ид измерения Реквизиты:
	reqs_id=db_dict["dims"]["names"]["Реквизиты"]
	#Создается манипулятор измерения Реквизиты:
	reqs=db.Dimension(reqs_id)
	#Создается словарь измерения Реквизиты:
	reqs_dict=reqs.dictionary()
	
	#Определяется текущая дата и время
	now=datetime.now()

	#Если год не передан в качестве аргумента функции:
	if not god:
		#Результат формируется для текущего года
		year=now.year
	#Иначе
	else:
		#Результат формируется для года переданного в качестве аргумента функции
		year=god

	#Определяется ид отчетного года
	year_id=years_dict["names"][str(year)]

	#Создается манипултор ячейки куба:
	c=db.Cell(None, cube_id)
	#Создается объект nda из куба
	requisites=c.Nda({years_id:[year_id]})

	#Создается пустой словарь результатов
	result={}

	#Для каждого элемента в измерении реквизитов:
	for elem in requisites.elems[reqs_id]:
		#Создается подобъект nda для данного реквизита
		requisite=requisites.subnda({reqs_id:[elem]})
		#В словарь результатов добавляется запись для реквизита со значением данных подобъекта nda
		result[reqs_dict["ids"][elem]]=requisite.data
	
	#В словарь добавляется отчетный год
	result["ОтчетГод"]=years_dict["ids"][year_id]
	
	#Если год не передан в качестве аргумента функции:
	if not god:
		#Дата отчета в результате заменяется на текущую дату
		result["ДатаДок"]=now.strftime('%d.%m.%Y')

	#Если ИдФайл в кубе не начинается с 'NO_NDFL2'
	if result["ИдФайл"][:8]!='NO_NDFL2':
		#Создается список элементов даты отчета
		datelist=result['ДатаДок'].split('.')
		#ИдФайл в результате заменяется на генерируемый из реквизитов
		result["ИдФайл"]="_".join(["NO_NDFL2", result["ИННЮЛ"][:4], result["КПП"][:4], result["ИННЮЛ"]+result["КПП"], "".join([datelist[2],datelist[1],datelist[0]]), result["ИдФайл"]])

	#end of function suite
	return result

def persons(base_name, cube_name, god=None):
	"This function returns sorted list of persons dictionaries from olap"
	#beginning of function suite
	
	address=['Гражд', 'Индекс', 'КодРегион', 'Район', 'Город', 'НаселПункт', 'Улица', 'Дом', 'Корпус', 'Кварт']
	
	#Создается манипулятор олап сервера
	srv=server("admin", "ivushka2011", None, None, None, "sa-pc247", 7921)
	#Создается словарь олап сервера
	srv_dict=srv.dictionary()
	#Определяется ид базы данных
	base_id=srv_dict["names"][base_name]
	
	#Создается манипулятор базы данных
	db=srv.Database(base_id)
	#Создается словарь базы данных
	db_dict=db.dictionary()
	#Определяется ид куба данных
	cube_id=db_dict["cubes"]["names"][cube_name]
	
	#Определяется ид измерения Годы:
	years_id=db_dict["dims"]["names"]["ОтчетГод"]
	#Создается манипулятор измерения Годы:
	years=db.Dimension(years_id)
	#Создается словарь измерения Годы:
	years_dict=years.dictionary()
	
	#Определяется ид измерения tabnom:
	tabs_id=db_dict["dims"]["names"]["tabnom"]
	#Создается манипулятор измерения tabnom:
	tabs=db.Dimension(tabs_id)
	#Создается словарь измерения tabnom:
	tabs_dict=tabs.dictionary()
	
	#Определяется ид измерения Инфо:
	infos_id=db_dict["dims"]["names"]["Инфо"]
	#Создается манипулятор измерения Инфо:
	infos=db.Dimension(infos_id)
	#Создается словарь измерения tabnom:
	infos_dict=infos.dictionary()
	
	#Определяется текущая дата и время
	now=datetime.now()

	#Если год не передан в качестве аргумента функции:
	if not god:
		#Результат формируется для текущего года
		year=now.year
	#Иначе
	else:
		#Результат формируется для года переданного в качестве аргумента функции
		year=god

	#Определяется ид отчетного года
	year_id=years_dict["names"][str(year)]

	#Создается пустой список персон
	persons=[]
	
	#Создается манипултор ячейки куба:
	c=db.Cell(None, cube_id)
	#Создается объект nda из куба
	tabs=c.Nda({years_id:[year_id]})
	
	for tab in tabs.elems[tabs_id]:
		person={"requisites":{}}
		infos=tabs.subnda({tabs_id:[tab]})
		for inf in infos.elems[infos_id]:
			info=infos.subnda({infos_id:[inf]})
			if infos_dict["ids"][inf]=="Адрес":
				addresslist=info.data.split(",")
				for x in range(len(address)):
					if addresslist[x]!="":
						person["requisites"][address[x]]=addresslist[x]
			else:
				if info.data!="":
					person["requisites"][infos_dict["ids"][inf]]=info.data
		person["requisites"]["tabnom"]=str(tabs_dict["ids"][tab])
	
		fio=[]
		for x in range(3):
			if ["Фамилия","Имя","Отчество"][x] in person["requisites"]:
				fio+=[person["requisites"][["Фамилия","Имя","Отчество"][x]]]
		person["fiotab"]=" ".join(fio)+" Таб. №"+person["requisites"]["tabnom"]
		persons+=[person]
	persons=sorted(persons, key=itemgetter("fiotab"))
	for x in range(len(persons)):
		persons[x]["requisites"]["НомСпр"]=str(x+1)

	return persons

def values(base_name, cube_name, persons, god=None):
	"This function returns sorted list of persons incomes from olap"
	#beginning of function suite

	#Создается манипулятор олап сервера
	srv=server("admin", "ivushka2011", None, None, None, "sa-pc247", 7921)
	#Создается словарь олап сервера
	srv_dict=srv.dictionary()
	#Определяется ид базы данных
	base_id=srv_dict["names"][base_name]
	
	#Создается манипулятор базы данных
	db=srv.Database(base_id)
	#Создается словарь базы данных
	db_dict=db.dictionary()
	#Определяется ид куба данных
	cube_id=db_dict["cubes"]["names"][cube_name]
	
	#Определяется ид измерения Годы:
	years_id=db_dict["dims"]["names"]["ОтчетГод"]
	#Создается манипулятор измерения Годы:
	years=db.Dimension(years_id)
	#Создается словарь измерения Годы:
	years_dict=years.dictionary()["names"]

	#Определяется ид измерения tabnom:
	tabs_id=db_dict["dims"]["names"]["tabnom"]
	#Создается манипулятор измерения tabnom:
	tabs=db.Dimension(tabs_id)
	#Создается словарь измерения tabnom:
	tabs_dict_n=tabs.dictionary()["names"]

	#Определяется ид измерения Ставка:
	rates_id=db_dict["dims"]["names"]["Ставка"]
	#Создается манипулятор измерения Ставка:
	rates=db.Dimension(rates_id)
	#Создается словарь измерения Ставка:
	rates_dict=rates.dictionary()["names"]

	#Определяется ид измерения Месяц:
	months_id=db_dict["dims"]["names"]["Месяц"]
	#Создается манипулятор измерения Месяц:
	months=db.Dimension(months_id)
	#Создается словарь измерения Месяц:
	months_dict=months.dictionary()["names"]

	#Определяется ид измерения КодДоход:
	koddohs_id=db_dict["dims"]["names"]["КодДоход"]
	#Создается манипулятор измерения КодДоход:
	koddohs=db.Dimension(koddohs_id)
	#Создается словарь измерения КодДоход:
	koddohs_dict=koddohs.dictionary()["ids"]
	koddohs_dict_n=koddohs.dictionary()["names"]

	#Определяется ид измерения КодВычет:
	kodvics_id=db_dict["dims"]["names"]["КодВычет"]
	#Создается манипулятор измерения КодВычет:
	kodvics=db.Dimension(kodvics_id)
	#Создается словарь измерения КодВычет:
	kodvics_dict=kodvics.dictionary()["ids"]

	#Определяется ид измерения Данные:
	dans_id=db_dict["dims"]["names"]["Данные"]
	#Создается манипулятор измерения Данные:
	dans=db.Dimension(dans_id)
	#Создается словарь измерения Данные:
	dans_dict_n=dans.dictionary()["names"]
	dans_dict_id=dans.dictionary()["ids"]
	
	#
	
	#Если год не передан в качестве аргумента функции:
	if not god:
		#Результат формируется для текущего года
		year=now.year
	#Иначе
	else:
		#Результат формируется для года переданного в качестве аргумента функции
		year=god

	#Определяется ид отчетного года
	year_id=years_dict[str(year)]
	#Определяется ид элемента измерения данные: СумДоход
	sumdoh_id=dans_dict_n['СумДоход']
	#Определяется ид элемента измерения данные: СумВычет
	sumvic_id=dans_dict_n['СумВычет']
	#Определяется ид элемента измерения данные: НалУдерж
	nalud_id=dans_dict_n['НалУдерж']
	#Формируется список ид элементов измерения данные: СумДоход, СумВычет, НалУдерж
	dan_id=[sumdoh_id, sumvic_id, nalud_id]
	#Определяется ид элемента измерения КодДоход: 0
	koddoh_id=koddohs_dict_n['0']
	
	#Создается манипултор ячейки куба:
	c=db.Cell(None, cube_id)
	#Создается объект nda из куба
	n=c.Nda({years_id:[year_id], dans_id:dan_id})
	
	for person in persons:
		
		tab_id=tabs_dict_n[person['requisites']['tabnom']]
		
		#Создается объект nda из куба
		rates=n.subnda({tabs_id:[tab_id]}, False)
		person['rates']={}
		
		for rate in rates.elems_filled[rates_id]:
			months=rates.subnda({rates_id:[rate]})
			person['rates'][rate]={'months':{}}
			person['rates'][rate]['kodvics']={}
			person['rates'][rate]['taxed']=0
			for month in months.elems_filled[months_id]:
				koddohs=months.subnda({months_id:[month]})
				person['rates'][rate]['months'][month]={'koddohs':{}}
				for koddoh in koddohs.elems_filled[koddohs_id]:
					kodvics=koddohs.subnda({koddohs_id:[koddoh]})
					for kodvic in kodvics.elems_filled[kodvics_id]:
						sums=kodvics.subnda({kodvics_id:[kodvic]})
						if koddohs_dict[koddoh]!='0':
							person['rates'][rate]['months'][month]['koddohs'][koddoh]={"КодДоход":koddohs_dict[koddoh]}
							person['rates'][rate]['months'][month]['koddohs'][koddoh]["КодВычет"]=kodvics_dict[kodvic]
							if dans_id in sums.dims_nda:
								if sumdoh_id in sums.elems_filled[dans_id]:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумДоход"]=sums.data[sums.elems[dans_id].index(sumdoh_id)]
								else:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумДоход"]=0
								if sumvic_id in sums.elems_filled[dans_id]:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумВычет"]=sums.data[sums.elems[dans_id].index(sumvic_id)]
								else:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумВычет"]=0
								if nalud_id in sums.elems_filled[dans_id]:
									person['rates'][rate]['taxed']+=sums.data[sums.elems[dans_id].index(nalud_id)]
							else:
								if sumdoh_id in sums.elems_filled[dans_id]:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумДоход"]=sums.data
								else:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумДоход"]=0
								if sumvic_id in sums.elems_filled[dans_id]:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумВычет"]=sums.data
								else:
									person['rates'][rate]['months'][month]['koddohs'][koddoh]["СумВычет"]=0
								if nalud_id in sums.elems_filled[dans_id]:
									person['rates'][rate]['taxed']+=sums.data
						else:
							person['rates'][rate]['kodvics'][kodvic]={"КодВычет":kodvics_dict[kodvic]}
							if dans_id in sums.dims_nda:
								person['rates'][rate]['kodvics'][kodvic]["СумВычет"]=sums.data[sums.elems[dans_id].index(sumvic_id)]
							else:
								person['rates'][rate]['kodvics'][kodvic]["СумВычет"]=sums.data
	return persons
